package com.dandelion.common.service;

import com.dandelion.common.dao.auto.mapper.UserSessionMapper;
import com.dandelion.common.dao.auto.pojo.UserSession;
import com.dandelion.common.dao.auto.pojo.UserSessionCriteria;
import com.dandelion.common.utils.CommonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.List;
import java.util.UUID;

@Service
public class UserSessionService {
    private static int EXPIRE_DAYS = 365;

    private static final Logger logger = LoggerFactory.getLogger(UserSessionService.class);

    @Autowired
    private UserSessionMapper userSessionMapper;

    public UserSession insertNewUserSession(long userId) {
        UserSession session = new UserSession();

        Calendar calendar = Calendar.getInstance();
        session.setCreateTime(calendar.getTime());

        session.setExpireTime(calendar.getTime());
        session.setUserId(userId);
        session.setUserToken(genUserToken());

        userSessionMapper.insertSelective(session);
        return session;
    }

    private String genUserToken() {
        String uuid = UUID.randomUUID().toString();
        StringBuilder builder = new StringBuilder(uuid.length() + 5);
        builder.append(System.currentTimeMillis()).append('-');
        for (int i = 0; i < uuid.length(); ++i) {
            if (uuid.charAt(i) == '-') {
                continue;
            }
            builder.append(uuid.charAt(i));
        }
        return builder.toString();
    }

    public UserSession updateUserSession(long userId) {
        UserSession session = new UserSession();

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, EXPIRE_DAYS);

        session.setExpireTime(calendar.getTime());
        session.setUserToken(genUserToken());

        UserSessionCriteria criteria = new UserSessionCriteria();
        criteria.createCriteria().andUserIdEqualTo(userId);

        userSessionMapper.updateByExampleSelective(session, criteria);
        return session;
    }

    public UserSession getValidUserSessionByToken(String token) {
        UserSessionCriteria criteria = new UserSessionCriteria();
        criteria.createCriteria().andUserTokenEqualTo(token);

        List<UserSession> sessionList = userSessionMapper.selectByExample(criteria);
        return CommonUtils.selectOne(sessionList);
    }

    public void expireUserSession(String token) {
        UserSession session = new UserSession();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -1);
        session.setExpireTime(calendar.getTime());

        UserSessionCriteria criteria = new UserSessionCriteria();
        criteria.createCriteria().andUserTokenEqualTo(token);
        userSessionMapper.updateByExampleSelective(session, criteria);
    }

    public boolean isExpired(UserSession session) {
        return session == null || session.getExpireTime() == null || session.getExpireTime().getTime() <= System.currentTimeMillis() / 1000;
    }
}
